package com.jmp.security.grant.crmApp;

import com.alibaba.fastjson.JSONObject;
import com.jmp.security.base.ClientDetail;
import com.jmp.security.base.UserDetail;
import com.jmp.security.base.UserDetailService;
import com.jmp.security.grant.wx.WxAppRquestDetail;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import one.stand.dto.WechatLoginDto;
import one.stand.dto.WechatUserInfoDto;
import one.stand.model.User;
import one.stand.service.UserService;
import one.stand.service.user.UserAdminService;
import org.apache.commons.lang3.StringUtils;

import java.util.Objects;

@Slf4j
public class CrmAppWxUserDetailServiceImpl implements UserDetailService<WxAppRquestDetail> {
    private UserAdminService userAdminService;
    private UserService userService;

    public CrmAppWxUserDetailServiceImpl(UserAdminService userAdminService, UserService userService) {
        this.userAdminService = userAdminService;
        this.userService = userService;
    }

    @Override
    public UserDetail get(WxAppRquestDetail requestDetail, ClientDetail clientDetail) {
        WxUserDetail userDetail = new WxUserDetail();
        appOauth(requestDetail, clientDetail, userDetail);

        if (Objects.isNull(userDetail.getUserModel())) {
            saveUser(requestDetail, clientDetail.getCompanyAccountModel().getCompanyId(), userDetail);
        } else {
            updateUser(userDetail.getUserModel(), requestDetail, clientDetail, userDetail.getWechatLoginDto(), userDetail.getUserInfoDto());
        }

        User inModel = userAdminService.getByUserId(userDetail.getUserModel().getUserId());//重新获取最新User信息
        userDetail.setUserModel(inModel);
        userDetail.setSessionKey(userDetail.getSessionKey());
        return userDetail;
    }

    private void updateUser(User inModel, WxAppRquestDetail request, ClientDetail clientDetail, WechatLoginDto wechatLoginDto, WechatUserInfoDto userInfoDto) {
        User userModel = new User();
        if (StringUtils.isBlank(inModel.getUnionid())
                && StringUtils.isNoneBlank(wechatLoginDto.getUnionId())) {
            userModel.setUserId(inModel.getUserId());
            userModel.setUnionid(wechatLoginDto.getUnionId());
        }
        final boolean isUpdateUserInfo = Objects.nonNull(userInfoDto);
        if (isUpdateUserInfo) {
            userModel.setUserId(inModel.getUserId());
            userModel.setNickeName(userInfoDto.getNickName());
            userModel.setAvatarUrl(userInfoDto.getAvatarUrl());
            userModel.setGender(userInfoDto.getGender());
            userModel.setCity(userInfoDto.getCity());
            userModel.setProvince(userInfoDto.getProvince());
            userModel.setCountry(userInfoDto.getCountry());
        }
        if (UserAdminService.GZH_STATE_NORMAl != inModel.getGzhState()
                && UserAdminService.GZH_STATE_APP != inModel.getGzhState()) {//更新用户 公众号状态
            userModel.setUserId(inModel.getUserId());
            userModel.setGzhState(UserAdminService.GZH_STATE_APP);
        }
        if (StringUtils.isBlank(inModel.getCrmOpenId())) {//crm登录 用户绑定
            userModel.setUserId(inModel.getUserId());
            userModel.setCrmOpenId(wechatLoginDto.getOpenId());
        }
        if (Objects.nonNull(userModel.getUserId())) {
            userService.update(userModel);
        }

        if (StringUtils.isNoneBlank(wechatLoginDto.getOpenId())) {
            userService.saveUserLoginWx(inModel.getUserId(), request.getLoginEnum().getAccountType(), request.getCompanyKey(), wechatLoginDto.getOpenId());
        }
    }

    private void saveUser(WxAppRquestDetail request, Integer companyId, WxUserDetail userDetail) {
        User inModel = new User();
        WechatLoginDto wechatLoginDto = userDetail.getWechatLoginDto();
        inModel.setUnionid(wechatLoginDto.getUnionId());
        inModel.setEnterpriseId(companyId);
        WechatUserInfoDto userInfoDto = userDetail.getUserInfoDto();
        if (Objects.nonNull(userInfoDto)) {
            inModel.setNickeName(userInfoDto.getNickName());
            inModel.setAvatarUrl(userInfoDto.getAvatarUrl());
            inModel.setGender(userInfoDto.getGender());
            inModel.setCity(userInfoDto.getCity());
            inModel.setProvince(userInfoDto.getProvince());
            inModel.setCountry(userInfoDto.getCountry());
        }
        inModel.setCrmOpenId(wechatLoginDto.getOpenId());
        userService.saveUser(inModel);

        if (StringUtils.isNoneBlank(wechatLoginDto.getOpenId())) {
            userService.saveUserLoginWx(inModel.getUserId(), request.getLoginEnum().getAccountType(), request.getCompanyKey(), wechatLoginDto.getOpenId());
        }

        userDetail.setUserModel(inModel);
    }

    private void appOauth(WxAppRquestDetail request, ClientDetail clientDetail, WxUserDetail userDetail) {
        String unionId = request.getAppOauth().getUnionid();
        String sessionKey = request.getAppOauth().getSessionKey();
        String openId = request.getAppOauth().getOpenId();
        String userInfo = request.getAppOauth().getUserInfo();
        WechatLoginDto wechatLoginDto = WechatLoginDto.builder()
                .openId(openId)
                .sessionKey(sessionKey)
                .unionId(unionId)
                .build();
        WechatUserInfoDto userInfoDto = JSONObject.parseObject(userInfo, WechatUserInfoDto.class);
        if (StringUtils.isBlank(wechatLoginDto.getUnionId()) && Objects.nonNull(userInfoDto)) {
            wechatLoginDto.setUnionId(userInfoDto.getUnionid());
        }
        User inModel = userService.getByUnionid(wechatLoginDto.getUnionId());
        if (Objects.isNull(inModel)) {//unionid查无用户时，通过openId查询用户
            inModel = userService.getByOpenId(request.getLoginEnum(), request.getCompanyKey(), wechatLoginDto.getOpenId());
        }

        userDetail.setWechatLoginDto(wechatLoginDto);
        userDetail.setUserInfoDto(userInfoDto);
        userDetail.setUserModel(inModel);
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class WxUserDetail extends UserDetail {
        private WechatLoginDto wechatLoginDto;
        private WechatUserInfoDto userInfoDto;
    }
}
